#ifndef UL_LOG_ADAPTER_H_ 
#define UL_LOG_ADAPTER_H_
#include <sys/types.h>
#include <ctype.h>
#include <stddef.h>
#include "ul_define.h"
namespace LinuxNetworkUtility
{
  typedef enum 
  {
    DEBUG,
    INFO,
    NOTICE,
    MONITOR,
    WARNING,
    ERROR
  }ul_log_level_t;

  /// @class abstract log adapter class
  class UlLogAdapter
  {
  public:
    UlLogAdapter()
    {
    }
    virtual ~UlLogAdapter()
    {
    }

    virtual int write_log(const ul_log_level_t level, const char *fmt, ...) = 0;
  };

  /// @class basic log adapter, print logs to stderr 
  class UlBasicLogAdapter:public UlLogAdapter
  {
  public:
    virtual int write_log(const ul_log_level_t level, const char *fmt, ...);
  };

  /// @property global log adapter used by the linux network library
  extern UlLogAdapter *g_ul_log_adapter;

  /// @def macros for writing log
  #define UL_LOG_DEBUG(fmt,args...)\
  g_ul_log_adapter->write_log(DEBUG,"[DEBUG] [%s:%d] [%lld]"fmt"\n", __FILE__, __LINE__,\
  static_cast<int64_t>(gettid()), ## args)

  #define UL_LOG_INFO(fmt,args...)\
  g_ul_log_adapter->write_log(INFO,"[INFO] [%s:%d] [%lld]"fmt"\n", __FILE__, __LINE__,\
  static_cast<int64_t>(gettid()), ## args)

  #define UL_LOG_WARNING(fmt,args...)\
  g_ul_log_adapter->write_log(WARNING,"[WARNING] [%s:%d] [%lld]"fmt"\n", __FILE__, __LINE__,\
  static_cast<int64_t>(gettid()), ## args)

  #define UL_LOG_MONITOR(fmt,args...)\
  g_ul_log_adapter->write_log(MONITOR,"[MONITOR] [%s:%d] [%lld]"fmt"\n", __FILE__, __LINE__,\
  static_cast<int64_t>(gettid()), ## args)

  #define UL_LOG_ERROR(fmt,args...)\
  g_ul_log_adapter->write_log(ERROR,"[ERROR] [%s:%d] [%lld]"fmt"\n", __FILE__, __LINE__,\
  static_cast<int64_t>(gettid()), ## args)

  /// @fn set log adapter for linux network utility library
  void set_ul_log_adaptor(UlLogAdapter * log_adapter = NULL);
}   
#endif /* UL_LOG_ADAPTER_H_ */
